﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace AMOOF {
    public partial class ModelSelection : UserControl {

        private string[] pdfs = {
                                "Transformed Beta",
                                "Generalized Pareto",
                                "Burr",
                                "Inverse Burr",
                                "Pareto",
                                "Inverse Paralogistic",
                                "Transformed Gamma",
                                "Inverse Transformed Gamma",
                                "Gamma",
                                "Inverse Pareto",
                                "Loglogistic",
                                "Paralogistic",
                                "Inverse Gamma",
                                "Weibull",
                                "Inverse Weibull",
                                "Exponential",
                                "Inverse Exponential",
                                "Lognormal",
                                "Inverse Gaussian",
                                "Single Parameter Pareto",
                                "Generalized Beta",
                                "Beta"
                            };

        private Thread m_solverThread;

        public ModelSelection() {
            InitializeComponent();


            btnGenerateExcelDocument.Text = "Generate Document";
            btnToggleSelectAll.Text = "Select All";

            for(int i = 0; i < gbxSelectPDFs.Controls.Count; i++) {
                try {
                    ((OnOffButton)gbxSelectPDFs.Controls["panel" + (i + 1)].Controls["onOffButton" + (i + 1)]).Selected = false;

                    gbxSelectPDFs.Controls["panel" + (i + 1)].Controls["onOffButton" + (i + 1)].MouseClick += new MouseEventHandler(btnPDF_Click);
                    gbxSelectPDFs.Controls["panel" + (i + 1)].Controls["onOffButton" + (i + 1)].Name = "btn" + pdfs[i].Replace(" ", String.Empty);
                    gbxSelectPDFs.Controls["panel" + (i + 1)].Controls["label" + (i + 1)].Text = pdfs[i];
                    gbxSelectPDFs.Controls["panel" + (i + 1)].Controls["label" + (i + 1)].Name = "lbl" + pdfs[i].Replace(" ", String.Empty);
                    gbxSelectPDFs.Controls["panel" + (i + 1)].Name = "pnl" + pdfs[i].Replace(" ", String.Empty);
                    
                }
                catch (Exception e) { Program.log(e.Message + "\r\n" + e.StackTrace); }
            }

            btnBoth.Text = "Run as Both";
            btnMixed.Text = "Run as Mixed";
            btnStandard.Text = "\u2713 Run as Single";

            btnStandard.Active = true;

            foreach (Control c in pnlPDFRunType.Controls) {
                if (c is ToggleButton) {
                    c.MouseClick += new MouseEventHandler(ToggleButton_MouseClick);
                }
            }

        }

        private void btnToggleSelectAll_Click(object sender, EventArgs e) {
            ((ToggleButton)sender).Active = ((ToggleButton)sender).Active ? false : true;
            ((ToggleButton)sender).Text = ((ToggleButton)sender).Active ? "\u2713 Select All" : "Select All";

            foreach (Control c in gbxSelectPDFs.Controls) {
                if (c is Panel) {
                    foreach (Control ci in c.Controls) {
                        if (ci is OnOffButton) {
                            ((OnOffButton)ci).Selected = ((ToggleButton)sender).Active;
                            btnPDF_Click(ci, e);
                        }
                    }
                }
            }
        }

        private void btnPDF_Click(object sender, EventArgs e) {
            if (((OnOffButton)sender).Selected) {
                ((OnOffButton)sender).Parent.Controls["lbl" + ((OnOffButton)sender).Name.Substring(3)].ForeColor = Color.White;
            }
            else {
                ((OnOffButton)sender).Parent.Controls["lbl" + ((OnOffButton)sender).Name.Substring(3)].ForeColor = Color.Black;
            }

        }

        private bool MouseIn(Control c, MouseEventArgs e) {
            if (e.X > 0 &&
                e.X < c.Width &&
                e.Y > 0 &&
                e.Y < c.Height) {
                return true;
            }

            return false;
        }

        private void ToggleButton_MouseClick(object sender, MouseEventArgs e) {
            Application.DoEvents();
            if (sender is ToggleButton && !((ToggleButton)sender).Active) {
                if (MouseIn((Control)sender, e)) {
                    foreach (Control c in  pnlPDFRunType.Controls) {
                        if (c is ToggleButton && ((ToggleButton)c).Active) {
                            ((ToggleButton)c).Text = ((ToggleButton)c).Text.Substring(2);
                            ((ToggleButton)c).Active = false;
                        }
                        else if (c is ToggleButton && c==sender ) {
                            ((ToggleButton)c).Text = "\u2713 " + ((ToggleButton)c).Text;
                            ((ToggleButton)sender).Active = true;
                        }
                    }
                }
            }
        }

        private void btnGenerateExcelDocument_Click(object sender, EventArgs e) {
            ((Control)sender).Enabled = false;
            Dictionary<string, Report> reports = new Dictionary<string, Report>();

            foreach (Control c in gbxSelectPDFs.Controls) {
                if (c.Name.Contains("pnl") && ((OnOffButton)c.Controls["btn" + c.Name.Substring(3)]).Selected) {
                    if (btnStandard.Active || btnBoth.Active) {
                        Report r = new Report();
                        r.PDF = Reflector.GetClass<PDF>("AMOOF." + c.Name.Substring(3));
                        reports.Add(c.Name.Substring(3), r);
                    }
                    if (btnMixed.Active || btnBoth.Active) {
                        Report r = new Report();
                        r.IsMixed = true;
                        PDF pdf = Reflector.GetClass<PDF>("AMOOF." + c.Name.Substring(3));
                        var greeks = pdf.Greeks.Keys;
                        r.PDF= new MultiplePDF(new List<PDF>() { pdf,pdf }, new List<double>() { .5, .5 });
                        r.PDF.Moment = pdf.Moment;
                        r.PDF.lnFunction = pdf.lnFunction;
                        r.PDF.function = pdf.function;
                        r.PDF.name = pdf.name;
                        foreach (var greek in greeks) {
                            r.PDF.Greeks.Add(greek, 1);
                            r.PDF.Greeks.Add(Reflector.GetEnum<PDF.Greek>(greek.ToString() + "2"), 1);
                        }

                        r.PDF.Greeks.Add(PDF.Greek.P1, .5);
                        r.PDF.Greeks.Add(PDF.Greek.P2, .5);
                        reports.Add("Mixed" + c.Name.Substring(3), r);
                    }
                }
            }

            FormAMOOF.Instance.LoadReports(reports);

            

            m_solverThread = new Thread(SetupSolver);
            m_solverThread.Start(new object[] { reports });

        }


        [STAThread]
        private void SetupSolver(object obj) {
            object content = ((object[])obj)[0];
            string statement = "Loading data into Excel document...";
            FormAMOOF.Instance.SetStatus(statement);

            Dictionary<string, Report> reports = (Dictionary<string, Report>)content;

            Solver solver = FormAMOOF.Instance.GetSolver();
            if (solver == null) {
                solver = new Solver();
            }

            FormAMOOF.Instance.SetProgress(0);

            foreach (object o in solver.LoadData(FormAMOOF.Instance.GetData(), 0)) {
                double dec = ((double)o * 10) % 10;
                if ((dec % 5) < 1) {
                    FormAMOOF.Instance.SetStatus(string.Format("{0}{1:00.00}% complete.", statement, o));
                    FormAMOOF.Instance.SetProgress((int)((double)o));
                }
            }

            //solver.LoadData(FormAMOOF.Instance.GetData());
            solver.LoadDataMoments(FormAMOOF.Instance.GetStatistics().DataMoments);

            statement = "Loading PDFs into Excel document... ";
            double counter = 1;
            foreach (var r in reports) {
                solver.BuildReport(r.Value);
                double percent = (counter/reports.Count)*100.0;
                FormAMOOF.Instance.SetStatus(string.Format("{0}{1:00.00}% complete.", statement, percent));
                FormAMOOF.Instance.SetProgress((int)percent);
                counter++;
            }

            FormAMOOF.Instance.SetStatus("Excel Document Successfully setup! Please set starting parameters and adjust contsraints for your PDFs");
            FormAMOOF.Instance.SetProgress(-1);
            FormAMOOF.Instance.LoadSolver(solver);

        }
    }
}
